{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# LSTM构建subword-level model进行文本分类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.0.0\n",
      "sys.version_info(major=3, minor=6, micro=10, releaselevel='final', serial=0)\n",
      "matplotlib 3.1.2\n",
      "numpy 1.18.1\n",
      "pandas 0.25.3\n",
      "sklearn 0.22.1\n",
      "tensorflow 2.0.0\n",
      "tensorflow_core.keras 2.2.4-tf\n"
     ]
    }
   ],
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "import tensorflow as tf\n",
    "from tensorflow import keras\n",
    "\n",
    "print(tf.__version__)\n",
    "print(sys.version_info)\n",
    "for module in mpl,np,pd,sklearn,tf,keras:\n",
    "    print(module.__name__,module.__version__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 Physical GPUs, 1 Logical GPUs\n"
     ]
    }
   ],
   "source": [
    "def solve_cudnn_error():\n",
    "    gpus = tf.config.experimental.list_physical_devices('GPU')\n",
    "    if gpus:\n",
    "        try:\n",
    "            # Currently, memory growth needs to be the same across GPUs\n",
    "            for gpu in gpus:\n",
    "                tf.config.experimental.set_memory_growth(gpu, True)\n",
    "            logical_gpus = tf.config.experimental.list_logical_devices('GPU')\n",
    "            print(len(gpus), \"Physical GPUs,\", len(logical_gpus), \"Logical GPUs\")\n",
    "        except RuntimeError as e:\n",
    "            # Memory growth must be set before GPUs have been initialized\n",
    "            print(e)\n",
    "\n",
    "solve_cudnn_error()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据读取：tfds 读取TensorFlow Dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow_datasets as tfds\n",
    "\n",
    "dataset, info = tfds.load(\n",
    "    'imdb_reviews/subwords8k:0.1.0', with_info = True, as_supervised = True)\n",
    "train_dataset, test_dataset = dataset['train'], dataset['test']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tfds.core.DatasetInfo(\n",
      "    name='imdb_reviews',\n",
      "    version=0.1.0,\n",
      "    description='Large Movie Review Dataset.\n",
      "This is a dataset for binary sentiment classification containing substantially more data than previous benchmark datasets. We provide a set of 25,000 highly polar movie reviews for training, and 25,000 for testing. There is additional unlabeled data for use as well.',\n",
      "    homepage='http://ai.stanford.edu/~amaas/data/sentiment/',\n",
      "    features=FeaturesDict({\n",
      "        'label': ClassLabel(shape=(), dtype=tf.int64, num_classes=2),\n",
      "        'text': Text(shape=(None,), dtype=tf.int64, encoder=<SubwordTextEncoder vocab_size=8185>),\n",
      "    }),\n",
      "    total_num_examples=100000,\n",
      "    splits={\n",
      "        'test': 25000,\n",
      "        'train': 25000,\n",
      "        'unsupervised': 50000,\n",
      "    },\n",
      "    supervised_keys=('text', 'label'),\n",
      "    citation=\"\"\"@InProceedings{maas-EtAl:2011:ACL-HLT2011,\n",
      "      author    = {Maas, Andrew L.  and  Daly, Raymond E.  and  Pham, Peter T.  and  Huang, Dan  and  Ng, Andrew Y.  and  Potts, Christopher},\n",
      "      title     = {Learning Word Vectors for Sentiment Analysis},\n",
      "      booktitle = {Proceedings of the 49th Annual Meeting of the Association for Computational Linguistics: Human Language Technologies},\n",
      "      month     = {June},\n",
      "      year      = {2011},\n",
      "      address   = {Portland, Oregon, USA},\n",
      "      publisher = {Association for Computational Linguistics},\n",
      "      pages     = {142--150},\n",
      "      url       = {http://www.aclweb.org/anthology/P11-1015}\n",
      "    }\"\"\",\n",
      "    redistribution_info=,\n",
      ")\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(info)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据集探索"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "vocabulary size: 8185\n"
     ]
    }
   ],
   "source": [
    "tokenizer = info.features['text'].encoder\n",
    "print('vocabulary size: {}'.format(tokenizer.vocab_size))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tokenized string is [6307, 2327, 2934, 7961, 9, 2724, 7975]\n",
      "original string is Tensorflow is cool.\n"
     ]
    }
   ],
   "source": [
    "# 编码解码\n",
    "sample_string = 'Tensorflow is cool.'\n",
    "tokenized_string = tokenizer.encode(sample_string)\n",
    "print('tokenized string is {}'.format(tokenized_string))\n",
    "\n",
    "original_string = tokenizer.decode(tokenized_string)\n",
    "print('original string is {}'.format(original_string))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6307 --> \"Ten\"\n",
      "2327 --> \"sor\"\n",
      "2934 --> \"flow\"\n",
      "7961 --> \" \"\n",
      "9 --> \"is \"\n",
      "2724 --> \"cool\"\n",
      "7975 --> \".\"\n"
     ]
    }
   ],
   "source": [
    "# subword\n",
    "for token in tokenized_string:\n",
    "    print('{} --> \"{}\"'.format(token, tokenizer.decode([token])))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From <ipython-input-8-6e39b9199140>:7: DatasetV1.output_shapes (from tensorflow.python.data.ops.dataset_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use `tf.compat.v1.data.get_output_shapes(dataset)`.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From <ipython-input-8-6e39b9199140>:7: DatasetV1.output_shapes (from tensorflow.python.data.ops.dataset_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use `tf.compat.v1.data.get_output_shapes(dataset)`.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(TensorShape([None, None]), TensorShape([None]))\n",
      "(TensorShape([None, None]), TensorShape([None]))\n"
     ]
    }
   ],
   "source": [
    "# 对dataset变换\n",
    "buffer_size = 10000\n",
    "batch_size = 64\n",
    "\n",
    "train_dataset = train_dataset.shuffle(buffer_size)\n",
    "# 对每一个batch，找到最长的sequence，做padding\n",
    "train_dataset = train_dataset.padded_batch(batch_size, train_dataset.output_shapes)\n",
    "test_dataset = test_dataset.padded_batch(batch_size, test_dataset.output_shapes)\n",
    "\n",
    "# shape: 数据 (batch_size, seq_length)，label(length)\n",
    "print(train_dataset.output_shapes)\n",
    "print(test_dataset.output_shapes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型构建：单层双向LSTM"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "embedding (Embedding)        (None, None, 16)          130960    \n",
      "_________________________________________________________________\n",
      "bidirectional (Bidirectional (None, 64)                12544     \n",
      "_________________________________________________________________\n",
      "dense (Dense)                (None, 32)                2080      \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 1)                 33        \n",
      "=================================================================\n",
      "Total params: 145,617\n",
      "Trainable params: 145,617\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "embedding_dim = 16 # 每个词Embedding成长度为16的向量\n",
    "batch_size = 128\n",
    "vocab_size = tokenizer.vocab_size\n",
    "\n",
    "bi_lstm_model = keras.models.Sequential([\n",
    "    keras.layers.Embedding(vocab_size, embedding_dim),\n",
    "    keras.layers.Bidirectional(keras.layers.LSTM(units=32, return_sequences=False)),\n",
    "    keras.layers.Dense(32, activation = 'relu'),\n",
    "    keras.layers.Dense(1, activation = 'sigmoid'),\n",
    "])\n",
    "bi_lstm_model.summary()\n",
    "bi_lstm_model.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/10\n",
      "391/391 [==============================] - 96s 246ms/step - loss: 0.5303 - accuracy: 0.7281 - val_loss: 0.0000e+00 - val_accuracy: 0.0000e+00\n",
      "Epoch 2/10\n",
      "391/391 [==============================] - 89s 227ms/step - loss: 0.3155 - accuracy: 0.8744 - val_loss: 0.3710 - val_accuracy: 0.8516\n",
      "Epoch 3/10\n",
      "391/391 [==============================] - 92s 234ms/step - loss: 0.2585 - accuracy: 0.9050 - val_loss: 0.4360 - val_accuracy: 0.8340\n",
      "Epoch 4/10\n",
      "391/391 [==============================] - 90s 229ms/step - loss: 0.2428 - accuracy: 0.9122 - val_loss: 0.4095 - val_accuracy: 0.8407\n",
      "Epoch 5/10\n",
      "391/391 [==============================] - 90s 230ms/step - loss: 0.1918 - accuracy: 0.9315 - val_loss: 0.4914 - val_accuracy: 0.8296\n",
      "Epoch 6/10\n",
      "391/391 [==============================] - 92s 235ms/step - loss: 0.1688 - accuracy: 0.9418 - val_loss: 0.4415 - val_accuracy: 0.8377\n",
      "Epoch 7/10\n",
      "391/391 [==============================] - 90s 231ms/step - loss: 0.1432 - accuracy: 0.9520 - val_loss: 0.5021 - val_accuracy: 0.8463\n"
     ]
    }
   ],
   "source": [
    "callbacks = [keras.callbacks.EarlyStopping(patience=5, min_delta=1e-3)]\n",
    "\n",
    "# 训练\n",
    "history_bi_lstm = bi_lstm_model.fit(\n",
    "    train_dataset, epochs = 10, validation_data = test_dataset, callbacks = callbacks)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeoAAAEzCAYAAAD+XEDdAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8li6FKAAAgAElEQVR4nO3deXxV1d3v8c/KPJOQCQKBhCkBEubBEQMKCAjYapVKLdqqt3Vsn/tYte1jW9tbbWnvU60oUuuD1rnqrSjgUDQFrCgyhHkSGUKAkCBDEkISsu4f+5CEEOAEkuyd5Pt+vfYrOeess/M7G8iXtfZeaxtrLSIiIuJNAW4XICIiImemoBYREfEwBbWIiIiHKahFREQ8TEEtIiLiYQpqERERDztnUBtjnjPGFBpj1p3hdWOMecIYs80Ys8YYM6TpyxQREWmf/OlRzwWuPsvrE4Devu0O4OkLL0tERETAj6C21i4GDp6lyVTgBetYBsQaYzo3VYEiIiLtWVOco+4C7K7zON/3nIiIiFygoCbYh2nguQbXJTXG3IEzPE5YWNjQbt26NcGPlzOprq4mIEDXCzY3Hefmp2Pc/HSMW8aWLVuKrLWJjXlPUwR1PpBa53FXoKChhtbaOcAcgIyMDLt58+Ym+PFyJrm5ueTk5LhdRpun49z8dIybn45xyzDG7Gzse5riv0/zgO/6rv6+CDhsrd3bBPsVERFp987ZozbGvALkAAnGmHzgF0AwgLV2NrAAmAhsA8qAW5urWBERkfbmnEFtrf32OV63wF1NVpGIiIjUaIpz1CIi0g5UVlaSn59PeXm526V4XlhYGF27diU4OPiC96WgFhERv+Tn5xMdHU1aWhrGNDThRwCstRQXF5Ofn096evoF70/X4ouIiF/Ky8uJj49XSJ+DMYb4+PgmG3lQUIuIiN8U0v5pyuOkoBYRkVYjKirK7RJanIJaRETEwxTUIiLS6lhruf/++8nKyiI7O5vXXnsNgL179zJq1CgGDRpEVlYWS5Ys4cSJE9xyyy01bf/7v//b5eobR1d9i4hIq/PWW2+xevVq8vLyKCoqYvjw4YwaNYqXX36Z8ePH87Of/YwTJ05QVlbG6tWr2bNnD+vWrQPg0KFDLlffOApqERFptF+9s54NBUeadJ/9UmL4xeT+frVdunQp3/72twkMDCQ5OZkrrriC5cuXM3z4cL73ve9RWVnJtddey6BBg+jRowfbt2/nnnvuYdKkSYwbN65J625uGvoWEZFWx1kU83SjRo1i8eLFdOnShZtvvpkXXniBuLg48vLyyMnJYdasWdx2220tXO2FUY9aREQazd+eb3MZNWoUzzzzDDNmzODgwYMsXryYmTNnsnPnTrp06cLtt99OaWkpK1euZOLEiYSEhHDdddfRs2dPbrnlFldrbywFtYiItDrf+MY3+PTTTxk4cCDGGH7/+9/TqVMnnn/+eWbOnElwcDBRUVG88MIL7Nmzh1tvvZXq6moAHn30UZerbxwFtYiItBolJSWAs6DIzJkzmTlz5imvz5gxgxkzZpz2vpUrV7ZIfc1B56hFREQ8TEEtIiLiYQpqERERD1NQi4iIeJiCWkRExMMU1CIiIh6moBYREfEwBbWIiLRZZ7t/9Y4dO8jKymrBas6PglpERMTDFNQiItJqPPDAAzz11FM1j3/5y1/yq1/9iiuvvJIhQ4aQnZ3N22+/3ej9lpeXc+utt5Kdnc3gwYP5+OOPAVi/fj0jRoxg0KBBDBgwgK1bt1JaWsqkSZMYOHAgWVlZNffCbi5aQlRERBpv4YOwb23T7rNTNkx47KxNpk2bxo9+9CPuvPNOAF5//XXee+89fvzjHxMTE0NRUREXXXQRU6ZMwRjj94+eNWsWAGvXrmXTpk2MGzeOLVu2MHv2bO677z6mT59ORUUFJ06cYMGCBaSkpDB//nwADh8+fJ4f2D/qUYuISKsxePBgCgsLKSgoIC8vj7i4ODp37sxPf/pTBgwYwFVXXcWePXvYv39/o/a7dOlSbr75ZgAyMzPp3r07W7Zs4eKLL+a3v/0tv/vd79i5cyfh4eFkZ2fzz3/+kwceeIAlS5bQoUOH5vioNdSjFhGRxjtHz7c5XX/99bzxxhvs27ePadOm8dJLL3HgwAFWrFhBcHAwaWlplJeXN2qfZ7q/9U033cTIkSOZP38+48eP59lnn2XMmDGsWLGCBQsW8NBDDzFu3DgefvjhpvhoDVJQi4hIqzJt2jRuv/12ioqK+Ne//sXrr79OUlISwcHBfPzxx+zcubPR+xw1ahQvvfQSY8aMYcuWLezatYuMjAy2b99Ojx49uPfee9m+fTtr1qwhMzOTjh078p3vfIeoqCjmzp3b9B+yDgW1iIi0Kv379+fo0aN06dKFzp07M336dCZPnsywYcMYNGgQmZmZjd7nnXfeyQ9+8AOys7MJCgpi7ty5hIaG8tprr/Hiiy8SHBxMp06dePjhh1m+fDn3338/AQEBBAcH8/TTTzfDp6yloBYRkVZn7draC9kSEhL49NNPG2x38v7VDUlLS2PdunUAhIWFNdgzfuihh3jooYdOeW78+PGMHz/+PKo+P7qYTERExMPUoxYRkTZt7dq1NVd0nxQaGspnn33mUkWNo6AWEZE2LTs7m9WrV7tdxnnT0LeIiPjtTNOY5FRNeZwU1CIi4pewsDCKi4sV1udgraW4uJiwsLAm2Z+GvkVExC9du3YlPz+fAwcOuF2K54WFhdG1a9cm2ZeCWkRE/BIcHEx6errbZbQ7GvoWERHxMAW1iIiIhymoRUREPExBLSIi4mEKahEREQ9TUIuIiHiYglpERMTDFNQiIiIepqAWERHxMAW1iIiIh/kV1MaYq40xm40x24wxDzbwegdjzDvGmDxjzHpjzK1NX6qIiEj7c86gNsYEArOACUA/4NvGmH71mt0FbLDWDgRygD8aY0KauFYREZF2x58e9Qhgm7V2u7W2AngVmFqvjQWijTEGiAIOAlVNWqmIiEg75M/ds7oAu+s8zgdG1mvzJDAPKACigRuttdX1d2SMuQO4AyAxMZHc3NzzKFn8VVJSomPcAnScm5+OcfPTMfYuf4LaNPBc/buGjwdWA2OAnsCHxpgl1tojp7zJ2jnAHICMjAybk5PT6ILFf7m5uegYNz8d5+anY9z8dIy9y5+h73wgtc7jrjg957puBd6yjm3AV0Bm05QoIiLSfvkT1MuB3saYdN8FYtNwhrnr2gVcCWCMSQYygO1NWaiIiEh7dM6hb2ttlTHmbuB9IBB4zlq73hjzA9/rs4FfA3ONMWtxhsofsNYWNWPdIiIi7YI/56ix1i4AFtR7bnad7wuAcU1bmoiIiGhlMhEREQ9TUIuIiHiYglpERMTDFNQiIiIepqAWERHxMAW1iIiIhymoRUREPExBLSIi4mEKahEREQ9TUIuIiHiYglpERMTDFNQiIiIepqAWERHxMAW1iIiIhymoRUREPExBLSIi4mEKahEREQ9TUIuIiHiYglpERMTDFNQiIiIepqAWERHxMAW1iIiIhymoRUREPExBLSIi4mEKahEREQ9TUIuIiHiYglpERMTDFNQiIiIepqAWERHxMAW1iIiIhymoRUREPExBLSIi4mEKahEREQ9TUIuIiHiYglpERMTDFNQiIiIepqAWERHxMAW1iIiIhymoRUREPExBLSIi4mEKahEREQ9TUIuIiHiYglpERMTDFNQiIiIepqAWERHxML+C2hhztTFmszFmmzHmwTO0yTHGrDbGrDfG/KtpyxQREWmfgs7VwBgTCMwCxgL5wHJjzDxr7YY6bWKBp4CrrbW7jDFJzVWwiIhIe+JPj3oEsM1au91aWwG8Ckyt1+Ym4C1r7S4Aa21h05YpIiLSPvkT1F2A3XUe5/ueq6sPEGeMyTXGrDDGfLepChQREWnPzjn0DZgGnrMN7GcocCUQDnxqjFlmrd1yyo6MuQO4AyAxMZHc3NxGFyz+Kykp0TFuATrOzU/HuPnpGHuXP0GdD6TWedwVKGigTZG1thQoNcYsBgYCpwS1tXYOMAcgIyPD5uTknGfZ4o/c3Fx0jJufjnPz0zFufjrG3uXP0PdyoLcxJt0YEwJMA+bVa/M2cLkxJsgYEwGMBDY2bakiIiLtzzl71NbaKmPM3cD7QCDwnLV2vTHmB77XZ1trNxpj3gPWANXAs9badc1ZuIiISHvgz9A31toFwIJ6z82u93gmMLPpShMRERGtTCYiIuJhCmoREREPU1CLiIh4mIJaRETEwxTUIiIiHqagFhER8TAFtYiIiIcpqEVERDxMQS0iIuJhCmoREREPU1CLiIh4mIJaRETEw1wL6spqt36yiIhI6+FaUO8trSb/6zK3fryIiEir4N7Qt4W7Xl5FRZW61iIiImfiWlAnhBvydh/itws2ulWCiIiI57kW1BHBhtsuS2fuv3fwTl6BW2WIiIh4mqtXfT8wIZOh3eN48M01bCsscbMUERERT3I1qIMDA3jypsGEBgdy50srKKuocrMcERERz3F9HnXnDuE8Pm0QWwtL+Pn/W4e11u2SREREPMP1oAa4vHciP7qyD2+t2sOry3e7XY6IeEX1CfjyYxILP3G7EhHXBLldwEn3jOnFFzsP8ot568nu0oGsLh3cLklE3HJgM+S9AmtehyN7SIvoBvanYIzblYm0OE/0qAECAgx/unEQ8ZEh3PnSSg4fq3S7JBFpSaXF8NkcmDMaZo2AT56A5P5w/f+wYugfFNLSbnkmqAHio0J58qYhFBw6xn/+PU/nq8Xbyo/A539xhmXLj7hdTetUVQEb34FXp8MfM2Dh/XCiEsb/Fv5jI0z/O2R9k+rAULcrFXGNZ4a+TxraPY6HJvbl1+9u4C9LtnPHqJ5ulyRyqvIj8Nkz8OmTUH6I/gCb/hvSL4eMidDnaohNdbtK77IW9qx0hrbXvQHHvobIJBj5v2DgNOiU7XaFIp7iuaAG+N6laXyx4yC/e28zg7vFMTyto9sliUD5YV9Az4LyQ9BnAoy6n1VfLGNwxF7YvBAW/KezJWdDxgRn6zwIAjw1eOWOw/mw5jXIexWKtkBgKGROgkE3QY/REOjJX0cirvPkvwxjDL+/fgCbnvyEu15ayfx7LycxWkNf4pKagH7S+T5jIlzxE0gZDMDhbUch5y4Y9xso2uoE9uaFsOQPsPj3EN0Z+ox33pc+CoLDXf5ALeh4iTO0nfcKfLUYsNDtYpj8BPSbCuGxblco4nmeDGqA6LBgnpo+hGtnfcJ9r67ib98fSWCALiaRFlR+GJbNhmWzGgzoBiX0drZL73Uujtr2IWxeAGvfgBVzITgCeo5xhsf7jIeopBb7OC2muhp2LHZ6zhvmQWUpxKVBzoMw4Abo2MPtCkVaFc8GNUDfzjH8+tosfvLGGh7/5xb+Y1yG2yVJe3DsEHw2G5Y95QvoSb6AHtS4/UTGO+dcB06DquOwY4mvt/0ebHoXMNB1uG+IfCIkZrTuK5sPbKkzpSofQmMg+3oY+G3odlHr/mwiLvJ0UAPcMCyVL3Yc5ImPtjG4exyjM9pgD0S84WRAf/oUHD8Mmdc4Ad154IXvOygUel3lbBP/APvW+kJ7ASz6lbPFpdee1+52MQQGX/jPbW5lB2Hdm05A71kBJhB6XQnjHnH+89GehvlFmonngxrgkalZrMk/zI9fW838ey+nS6z+8UsTOnYIlj3tbE0d0A0xBjoPcLacB+BIAWx5zwnu5X91evJhHaD3OGeIvNdV3jqXW1UBWz9wwnnL+1BdCclZMO7/QPa3IDrZ7QpF2pRWEdRhwYE8/Z2hTP7zUu56aSWv/6+LCQnSVbRygY597Qvo2XUC+gEnQFtSTAoM+56zHS+B7R87w+Nb3oO1f4eAIOh+qdNDzbjaOd/b0qyFgpXOeee1b8Cxg5pSJdJCWkVQA6QnRDLz+gH88KWV/HbBRn45pb/bJUlrVRPQT8PxI9B3shPQXgib0Cinnr6TnXWu879whsc3L4T3HnC2pH6157VThjTv1K/De+pMqdpcO6Vq4Ledi+I0pUqk2bWqf2UTsjvz/cvS+evSrxiWFsc1A1LcLklak2NfO+efP5vtvYBuSEAgdBvpbGN/BcVf1g6RL/0TLPmj06s9OfWrRw6ERFz4z60orZ1Stf1f1E6pehz6XeutYXiRdqBVBTXAgxMyWbXrax54Yw19O8fQMzHK7ZLE68oOOr3nmoCe4gvoLLcra5z4nnDxXc5WdhC2LXJ62xvehlV/g6AwZ+GQjAnOue3GnCuurnauSs971dlfZSnEdneO08AbNaVKxEWtLqiDAwN48qYhXPPnpdz54kr+cdelhIcEul2WeFHZQefCrGWzoeKos8DGqJ+0voBuSERHGPAtZ6uqgJ2f1C60smWh06bL0Noh8qR+DU+PKtrq9JzzXqszpeo6GHiTplSJeESrC2qAlNhw/nTjIGb8z+f87B9r+eO3BmL0C0VOKjvoLPP52TO1AX3FA86dmNqioBDoOdrZJvwOCjfUntf+6DfOFtvNWfI0Y4IT2hvnOb3nPV+ACYCeVzrD65mTNKVKxGNaZVADjOqTyL1jevP4oq2MSOvItBHd3C5J3HZaQF/rTLNqqwHdEGOcz5vcH0bdD0f3OVOoNi+Elc/D58/Utk3q7yx7mv0tiO7kXs0iclatNqgB7r2yNyt3fc3D89aT3bUD/VM6uF2Sd3y9g84F78HmcmfFq9huzsVJbVHZQWcd7s+ecS6E6n+tM8Sd3M/tytwX3QmGznC2ijLYnuv0uPuM9+5FdCJyilYd1IEBhj/dOIhJTyzlzpdWMu/uy+gQ3gpWc2ouVRXOkOfK5+HLj8nAwpanndeCwiC+NyT2gcRMSOjjBHjHns7QaWtUWuwE9OdzFND+CImAzInOJiKtRqsOaoD4qFBmTR/Mjc8s4/6/5/HMzUPb3/nq4i+dcF79MpQegJiukPMgn5d2ZUR2Lziw2bmt4IHNkL/cWfLxJBPoXNGbmFEb3ie/D4l07zOdzWkB/Q1niDupr9uViYg0uVYf1ABDu3fkwQmZ/Gb+Rv669Ctuu7wdTCWpLHdu7LBirjOtxgQ6FwoNmeGstRwQSFlurnPlbreLTn1vRalzte/J8C7a7Hzd8h5UV9W265BaL7x9XyNcuj94aTF8+mf4bA5UlkHWN50edFKmO/WIiLQA14I6omyPc+FP5qQmWRLx+5el88WOr3l04SYGpsYyPM2lMGluhZuc3nPeK84CHrHdYcx/waDpENPZv32ERDp3gqp/N6gTlXBw+6nhfWAz7Pw3VB2rbReR4AyfJ/bxhbdvOD26c/NM5yktgn//GT7/iwJaRNod14La2Gp4/6fOlpwNfa9xQjs567x+2Rtj+P23BjDlz0u5++WVzL/3chKiQpuhchdUlMGGf8CK52H3MggIdo7V0BmQntN0S0gGBtf2nuuqrobDu3098E21Q+nr3oLyQ7XtQqLrhHedIfS4tPO7kO20gL7OGeKuX5+ISBvmWlCXRqbCvQth0wJnCDf3Mch91OkhZl7jBHfqyEb9go8JC2bW9CF886l/c9+rq3jheyMJDGjF56v3rXXCec3rzk0jOvaEsY84i1FEJbZcHQEBENfd2XqPrX3eWigprO19nxxK//IjyHu5tl1gKMT3OjW8EzOc54Ia+M9UaRH8+wn4/FknoLOvd6YaKaBFpB3yK6iNMVcDjwOBwLPW2sfO0G44sAy40Vr7xjl33LEHXHK3s5UccK5Y3jQflv8Fls1yhlgzJjjB3SMHgsPOucv+KR349dQsfvLmGh5ftJX/GNvHn4/oHcdLnIu9Vj7v3N83MBT6TYGhtzh3UPLShXLGOMtURidD+qhTXzt2yHcevM4QesFKWP//AOt7f4BzD+aa8M6EAxudHnRVOWSdDOhW9mcoItKEzhnUxphAYBYwFsgHlhtj5llrNzTQ7nfA++dVSVRi7XzP40dh2z9h47u16xgHR0LvqyBzstOrO8uNAW4YnsryHQf580dbGdItlpyMpPMqqcVYCwWrnHBe+wZUlDihdfVjMOBG9y7euhDhsZA63NnqqjwGxdtqw7toMxzYAls/dO5rbAIU0CIidfjTox4BbLPWbgcwxrwKTAU21Gt3D/AmUO8383kIjXam3PT/hjM3eMdip6e9ab4T3AFBTg8ucxJkTGrwIqpHpmaxds9hfvzaaubfezkpsR5cFrH8sHO/4RXPw741EBTuXCg1ZAakjvBW77mpBIc7C23UX2zjRBV8vcMZCo9NdaU0EREv8ieouwC76zzOB0bWbWCM6QJ8AxhDUwR1XUEh0OsqZ5v4R2c4eNM7Tm97/v92ti7DnNDuOxkSegMQHhLIU9OHMOXJT7jr5ZW8dsfFhAQ14317/WWtM5d5xfOw/i3nHGxyNkz8g7OUY3u9hWBgECT0crsKERHPMdbaszcw5lvAeGvtbb7HNwMjrLX31Gnzd+CP1tplxpi5wLsNnaM2xtwB3AGQmJg49PXXXz//yq0lomw3CUWfkVC0jJij2wAojehKUcJFFCWM5Gh0L5bvr2bW6uOM7R7E9L7uXQUeVHmU5P25pBR8QGTZLqoCwyhMGsXezuM4Gt2rWXrPJSUlREXpNqDNTce5+ekYNz8d45YxevToFdbaYY15jz9BfTHwS2vteN/jhwCstY/WafMVcDJpEoAy4A5r7T/OtN+MjAy7efPmxtR6dofza68g37EU7AmIToHMibxwKJtH1sbx+E0jmDTAz7nGTcFaZw7yirnOkP2J45AyxDkPn3WdM8TfjHJzc8nJyWnWnyE6zi1Bx7j56Ri3DGNMo4Pan6Hv5UBvY0w6sAeYBtxUt4G1Nr1OEXNxetRnDOlm0aErjLzD2coOwtYPYOM7sOolvlt1jG+GR/Hxm4PZX3YzyUOuad7lMUuLnOU8V74AxVude/wOudk599x5QPP9XBERaXPOGdTW2ipjzN04V3MHAs9Za9cbY37ge312M9fYeBEdYeA0Z6sog+0fE5D3Dy7fuIDY95Zg/xmG6THamavdZwJExl/4z6yudi56WzHXOX9eXenMA7/sKedmEV5dN1tERDzNr3nU1toFwIJ6zzUY0NbaWy68rCYUEgGZk4jInMTyTXuZ/cLfuLPjJi7f/zlsWehMB+p2iXMxWuYkZ1GPxji6H1a/6PSev94BYbEw4nYY8l3dJEJERC5Ym7gph7+uyOzMitHXcvOirfz+m7/khq4HnXPam+bD+w85W6dsZ6525iRI7t/wRV7VJ5zVt1bMrb2RRdrlMPrnzpXnfizMIiIi4o92FdQA913Zm5U7v+a/5q2n/52X0H/Mz2HMz51bRW6a71vO9FHI/a2zRnXmNc6WOgKO7oNVLzoLsBze7aycdtGdzrlnTS0SEZFm0O6COjDA8Kdpg5j0xBLufGkl79xzGTFhwRDfEy6919mO7q9dzvTzOc69j8PjnAVKbDX0GA3jfu0sthIU4vZHEhGRNqzdBTVAQlQos24awo1zlnH/3/OY/Z2hmLpD3NHJMOxWZys/Ats+dJa4jEmBwTdDx/Qz71xERKQJtcugBhiW1pGHJmTym/kb+evSr7jt8h4NNwyLceY8Z13XsgWKiIgAHlhT0z3fvyyd8f2TeWzhJr7YcdDtckRERE7TroPaGMPvrx9Il7hw7n55FcUlx90uSURE5BTtOqgBOoQH89T0IRwsq+BHr63mRPXZl1QVERFpSe0+qAH6p3Tg11P7s2RrEU8s2up2OSIiIjUU1D43DEvluiFdeeKjrSzecsDtckRERAAFdQ1jDL+5NouM5Gjue3UVBYeOuV2SiIiIgrqu8JBAnpo+hMoTlrtfXklFVbXbJYmISDunoK6nR2IUv7tuACt3HeKxhZvcLkdERNo5BXUDJg3ozC2XpPHcJ1+xYO1et8sREZF2TEF9Bj+d2JdBqbH85I01fFVU6nY5IiLSTimozyAkKIBZ04cQFGj44YsrOFZxwu2SRESkHVJQn0WX2HD+dOMgNu8/ysNvr3O7HBERaYfa7U05/JWTkcQ9o3vxxEfbCAsO5MbhqfRPiTn1blsiIiLNREHth/uu6kPB4XJe+XwXf1u2kx6JkUwekMKUQSn0TIxyuzwREWnDFNR+CAww/OFbA/nZxL4sXLePd/IKeOKjrTy+aCv9U2KYMjCFyQNTSIkNd7tUERFpYxTUjRAXGcJNI7tx08hu7D9Szrtr9jIvr4BHF27i0YWbGJ4Wx5SBKUzI7kxCVKjb5YqISBugoD5PyTFhfP+ydL5/WTo7i0t5J6+AeXkF/Nfb6/nlOxu4pGc8UwamMD6rEzFhwW6XKyIirZSCugl0j4/k7jG9uXtMbzbtO1IT2ve/sYaf/WMdozMSmTKwC1f2TSIsONDtckVEpBVRUDexzE4xZHaK4T/HZbB69yHm5RXw7pq9vL9+P5EhgYztl8yUQSlc3juR4EDNjhMRkbNTUDcTYwyDu8UxuFscP5/Uj8+2FzMvr4CF6/bxj9UFxEYEMyGrM1MGpjAivSOBAZruJSIip1NQt4DAAMMlvRK4pFcCj0zNYvGWA8zLK+Afq/bwyue7SI4J5ZoBKUwZmMKArh00R1tERGooqFtYSFAAV/VL5qp+yZRVVLFoYyHz8gr426c7+evSr+geH1EzR7tPcrTb5YqIiMsU1C6KCAlism8O9uFjlby/bh/z8gp4KncbT368jcxO0Uwe6PS0UztGuF2uiIi4QEHtER3Cg7lheCo3DE+l8Gg5C3xztGe+v5mZ729mcLdYJg9I4ZoBnUmKCXO7XBERaSEKag9Kig7jlkvTueXSdHYfLKtZWOWRdzfwm/kbuKiHM0d7QlZnOkRojraISFumoPa41I4R/DCnJz/M6cm2wqPMW+3M0X7wrbX819vruKJPIpMHpnBV32QiQ/XHKSLS1ug3eyvSKyma/xiXwY/H9mHtnsPMW+3M0f7nxkLCgwO5sm8SUwamcEVGIqFBWlhFRKQtUFC3QsYYBnSNZUDXWH46sS/LdxxkXl4BC9bu5d01e4kJC+LqrE50tVWkF5eSFB1GeIiCW0SkNVJQt3IBAYaRPeIZ2SOeX07pz9JtRbyzuoD5a/ZSWnGC/7siF4Co0CCSogqdqvwAAA2RSURBVENJ9G1J0WG+r77HMaEkRoUSFxFCgBZfERHxDAV1GxIcGMDojCRGZyRRXnmCZ9/OJSmtDweOHq/ZCo+Ws27PYQqPFlJWceK0fQQFGBKiaoP75NfEmLCax0nRoSREhWrdchGRFqCgbqPCggPJSggkZ1jqGduUHq+isE6AO1+P13wtOFxOXv4hiksrsPb093cIDz61V36G3nqH8GCttiYicp4U1O1YZGgQ6aFBpCdEnrVd1YlqiksrKDxynAMl5c7XU0K9nJW7vqbwyHGOV1Wf9v6QoACnV36WME+KcXrpulGJiMipFNRyTkGBASTHhJEcEwZ0OGM7ay1Hj1fVCfLyesPux9lRXMryHQf5uqyywX10j4/gysxkxvZLZnhaHEEKbhFp5xTU0mSMMcSEBRMTFkyvpKiztq2oqqao5NReeeGR46zJP8SLn+3kuU++IjYimDGZSYzrl8yoPolEhOivq4i0P/rNJ64ICQogJTaclNjw014rPV7F4i0H+GDDfhZtLOStlXsIDQrgsl4JjO2XzJV9k0mMDnWhahGRlqegFs+JDA1iQnZnJmR3pvJENct3HOSD9fv5cMN+Fm0qxJi1DOkWx9h+zhB5z8Sz995FRFozBbV4WnBgAJf0TOCSngn8YnI/Nu49yocb9vPBhn08tnATjy3cRM/ESMb268TYfskMTo3VPHARaVMU1NJqGGPolxJDv5QY7ruqN3sOHeOfvtB+dsl2Zv/rSxKjQ7mqbxJj+yVzSc8EzfUWkVZPQS2tVpfYcGZcksaMS9I4XFZJ7pZCPli/n3mrC3jl891EhARyRZ9ExvZLZkxmErERIW6XLCLSaApqaRM6RAQzdVAXpg7qwvGqE3z6ZTEfbnDOay9ct4/AAMOItI4157VTO0a4XbKIiF8U1NLmhAYFkpORRE5GEr+emsWaPYf5cMM+Pli/n0fe3cAj726gb+cYxvZLZly/ZPqnxGjlNBHxLL+C2hhzNfA4EAg8a619rN7r04EHfA9LgB9aa/OaslCR8xEQYBiUGsug1FjuH5/JjqLSmovRnvxoK08s2kqX2HCu6pvEuP6dGJHeUaujiYinnDOojTGBwCxgLJAPLDfGzLPWbqjT7CvgCmvt18aYCcAcYGRzFCxyIdISIrl9VA9uH9WD4pLjLNpUyIcb9vPaF7t5/tOdxIQFMTrTuRjtij6JRIcFu12yiLRz/vSoRwDbrLXbAYwxrwJTgZqgttb+u077ZUDXpixSpDnER4Vyw7BUbhiWyrGKEyzZeqBmrvbbqwsICQzg4p7xNee1nSVURURalrEN3RapbgNjrgeuttbe5nt8MzDSWnv3Gdr/J5B5sn291+4A7gBITEwc+vrrr19g+XI2JSUlREVpMZDGqraWrV9Xs6qwipWFJygsc/6N9OgQwOCkQIYkB5ESaWrOa+s4Nz8d4+anY9wyRo8evcJaO6wx7/GnR93QVTYNprsxZjTwfeCyhl631s7BGRYnIyPD5uTk+FelnJfc3Fx0jM/PGN9Xay1bC0t857X38+bWQ7y5tZK0+AjG9ktibL9OVGzP03FuZvq73Px0jL3Ln6DOB+re1LgrUFC/kTFmAPAsMMFaW9w05Ym4yxhDn+Ro+iRHc9foXuw/Ul4z7Wvuv3fwlyVfYYCU5R/RPT6C7vGRpMVHkJYQSVp8JN3jI7ToiohcEH+CejnQ2xiTDuwBpgE31W1gjOkGvAXcbK3d0uRVinhEckwY37moO9+5qDtHyytZurWIDz5bC9Ed2VFcyvvr93GwtOKU93TuEEb3+AjS4iN9AX4y0CMJD1GIi8jZnTOorbVVxpi7gfdxpmc9Z61db4z5ge/12cDDQDzwlO+8XVVjx+BFWpvosGAmZHcmvHgzOTmDap4/XFbJzoOl7CguY0dRKTuKS9lZXMaHG/ZTXC/Ek2NC6R4fSXp8JN0TfGHu64lHhmqZAxHxcx61tXYBsKDec7PrfH8bcNrFYyLtUYeIYAZExDKga+xprx0pr2RXcRlfFZWys9gJ853FpSzaVEhRyfFT2iZGhzrD6L6e+Mleeff4CE0bE2lH9F92kRYUExZMVpcOZHXpcNprJcernPAuKvP1wp3v/7XlAH9fkX9K24SoEF9o1zsnnhBBjEJcpE1RUIt4RFRoEP1TOtA/5fQQLz1exU5f77vukPon24p4c2X5KW07RobU9MS7x0eSVmdIvUOEQlyktVFQi7QCkaFBNbf4rK+soopdB8tO64kv217MW6v2nNI2LiKY7vGR9EiMpGdilG9zAj0kSEuniniRglqklYsICSKzUwyZnU4P8fLKE74Qd3rgO4rL+OqA0xN/a2VtiAcGGFLjwumZGFUb4klR9EiIpGNkiG5aIuIiBbVIGxYWHFgzD7y+o+WVfFVUyvYDpXx5oKTm65JtRVRUVde0i40IpkdCpC/EnR54z6QounWM0A1MRFqAglqknYoOC2ZA19OvTj9RbSk4dIxtdcJ7+4EScutd1BYUYOgWH0GPhCh6JkXWDKP3TIwiNiKkpT+OSJuloBaRUwQGGFI7RpDaMYLRGae+dqS80gnvwhK2F5XwZWEp24tKWLzlABUnanvhHSND6JkYeUqI90iMIjUunCD1wkUaRUEtIn6LCQuuub93XVUnqtlz6BhfHqgN7y8LS1m0aT+vfVG7yEtwoKF7fKQT4nUuZuuRGEWHcF2RLtIQBbWIXLCgwAC6+6aDjck89bXDZZV8WVTi64U7vfEvD5SyaGMhVdW19/dJiAqtczV67VXpXeLCW/jTiHiLglpEmlWHiGCGdItjSLe4U56vPFHN7oNlp13MVn+99JCgAPrGGXRjJ2mvFNQi4orgwAB6+M5dX0XyKa99XVpRM3z+5YESDuzd7VKVIu5TUIuI58RFhjA0siNDu3cEIDd3v8sVibhHl1+KiIh4mIJaRETEwxTUIiIiHqagFhER8TAFtYiIiIcpqEVERDxMQS0iIuJhCmoREREPU1CLiIh4mIJaRETEwxTUIiIiHqagFhER8TAFtYiIiIcpqEVERDxMQS0iIuJhCmoREREPU1CLiIh4mIJaRETEwxTUIiIiHqagFhER8TAFtYiIiIcpqEVERDxMQS0iIuJhCmoREREPU1CLiIh4mIJaRETEwxTUIiIiHqagFhER8TAFtYiIiIcpqEVERDxMQS0iIuJhCmoREREPU1CLiIh4mF9BbYy52hiz2RizzRjzYAOvG2PME77X1xhjhjR9qSIiIu3POYPaGBMIzAImAP2Abxtj+tVrNgHo7dvuAJ5u4jpFRETaJX961COAbdba7dbaCuBVYGq9NlOBF6xjGRBrjOncxLWKiIi0O/4EdRdgd53H+b7nGttGREREGinIjzamgefsebTBGHMHztA4wHFjzDo/fr6cvwSgyO0i2gEd5+anY9z8dIxbRkZj3+BPUOcDqXUedwUKzqMN1to5wBwAY8wX1tphjapWGkXHuGXoODc/HePmp2PcMowxXzT2Pf4MfS8Hehtj0o0xIcA0YF69NvOA7/qu/r4IOGyt3dvYYkRERORU5+xRW2urjDF3A+8DgcBz1tr1xpgf+F6fDSwAJgLbgDLg1uYrWUREpP3wZ+gba+0CnDCu+9zsOt9b4K5G/uw5jWwvjadj3DJ0nJufjnHz0zFuGY0+zsbJWBEREfEiLSEqIiLiYa4E9bmWJJULY4xJNcZ8bIzZaIxZb4y5z+2a2ipjTKAxZpUx5l23a2mrjDGxxpg3jDGbfH+nL3a7prbGGPNj3++KdcaYV4wxYW7X1NoZY54zxhTWnYZsjOlojPnQGLPV9zXOn321eFD7uSSpXJgq4H9ba/sCFwF36Rg3m/uAjW4X0cY9Drxnrc0EBqLj3aSMMV2Ae4Fh1tosnIuGp7lbVZswF7i63nMPAoustb2BRb7H5+RGj9qfJUnlAlhr91prV/q+P4rzi00rxTUxY0xXYBLwrNu1tFXGmBhgFPBXAGtthbX2kLtVtUlBQLgxJgiIoIF1MKRxrLWLgYP1np4KPO/7/nngWn/25UZQa7nRFmSMSQMGA5+5W0mb9CfgJ0C124W0YT2AA8D/+E4xPGuMiXS7qLbEWrsH+AOwC9iLsw7GB+5W1WYln1xjxPc1yZ83uRHUfi03KhfOGBMFvAn8yFp7xO162hJjzDVAobV2hdu1tHFBwBDgaWvtYKAUP4cLxT++86RTgXQgBYg0xnzH3aqkLjeC2q/lRuXCGGOCcUL6JWvtW27X0wZdCkwxxuzAOX0zxhjzorsltUn5QL619uSI0Bs4wS1N5yrgK2vtAWttJfAWcInLNbVV+0/eWdL3tdCfN7kR1P4sSSoXwBhjcM7pbbTW/l+362mLrLUPWWu7WmvTcP4Of2StVS+kiVlr9wG7jTEnb2RwJbDBxZLaol3ARcaYCN/vjivRBXvNZR4ww/f9DOBtf97k18pkTelMS5K2dB1t3KXAzcBaY8xq33M/9a0wJ9La3AO85PuP/Xa0RHGTstZ+Zox5A1iJM2NkFVql7IIZY14BcoAEY0w+8AvgMeB1Y8z3cf6D9C2/9qWVyURERLxLK5OJiIh4mIJaRETEwxTUIiIiHqagFhER8TAFtYiIiIcpqEVERDxMQS0iIuJhCmoREREP+/9BKCgRBycrkgAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 576x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def plot_learning_curves(history, label, epochs, min_value, max_value):\n",
    "    data = {}\n",
    "    data[label] = history.history[label]\n",
    "    data['val_'+label] = history.history['val_'+label]\n",
    "    pd.DataFrame(data).plot(figsize=(8, 5))\n",
    "    plt.grid(True)\n",
    "    plt.axis([0, epochs, min_value, max_value])\n",
    "    plt.show()\n",
    "\n",
    "plot_learning_curves(history_bi_lstm, 'accuracy', 10, 0, 1)\n",
    "plot_learning_curves(history_bi_lstm, 'loss', 10, 0, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "391/391 [==============================] - 28s 72ms/step - loss: 0.5021 - accuracy: 0.8463\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[0.5020637243147701, 0.84632]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bi_lstm_model.evaluate(test_dataset)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
